
package uk.org.cardboardbox.nfcpointstracker;

import uk.org.cardboardbox.nfcpointstracker.model.Persistable;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class Database {

    private static final String TAG = Database.class.getCanonicalName();

    private static final int VERSION = 17;

    private static final String NAME = "database";

    private SQLiteOpenHelper helper;

    public Database(Context context) {
        helper = new SQLiteOpenHelper(context, NAME, null, VERSION) {
            @Override
            public void onCreate(SQLiteDatabase db) {
                Log.d(TAG, "Creating database");
                try {
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException();
                }
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                try {
                } catch (Exception e) {
                    e.printStackTrace();
                }
                onCreate(db);
            }
        };
    }

    public void persist(Persistable persistable) {
        synchronized (this) {
            SQLiteDatabase db = helper.getWritableDatabase();
            if (db.isOpen()) {
                try {
                    if (persistable.getId() == -1) {
                        Log.d(TAG, "inserting");
                        persistable.markCreated();
                        db.insert(persistable.getTable(), null, persistable.getContentValues());
                    } else {
                        Log.d(TAG, "updating");
                        persistable.markUpdated();
                        db.update(persistable.getTable(), persistable.getContentValues(),
                                persistable.getIdKey() + "=?", new String[] {
                                    Long.toString(persistable.getId())
                                });
                    }
                } catch (SQLiteException ex) {
                    ex.printStackTrace();
                    throw new RuntimeException("Failed insert or update");
                } finally {
                    db.close();
                }
            }
        }
    }

    public interface QueryCallback {
        public void onResult(Cursor cursor);
    }

    public void query(String table, String idKey, long id, QueryCallback callback) {
        query(table, idKey + "= ?", new String[] {
            Long.toString(id)
        }, callback);
    }

    public void query(String table, String selection, String[] args, QueryCallback callback) {
        synchronized (this) {
            SQLiteDatabase db = helper.getReadableDatabase();
            if (db.isOpen()) {
                Cursor c = db.query(table, null, selection, args, null, null, null);
                if (c.moveToFirst()) {
                    while (!c.isAfterLast()) {
                        if (callback != null)
                            callback.onResult(c);
                        c.moveToNext();
                    }
                }
                c.close();
                db.close();
            }
        }
    }

    public void query(String table, QueryCallback callback) {
        synchronized (this) {
            SQLiteDatabase db = helper.getReadableDatabase();
            if (db.isOpen()) {
                Cursor c = db.query(table, null, null, null, null, null, null);
                if (c.moveToFirst()) {
                    while (!c.isAfterLast()) {
                        if (callback != null)
                            callback.onResult(c);
                        c.moveToNext();
                    }
                }
                c.close();
                db.close();
            }
        }
    }

    public void delete(Persistable persistable) {
        synchronized (this) {
            SQLiteDatabase db = helper.getWritableDatabase();
            if (db.isOpen()) {
                db.delete(persistable.getTable(), persistable.getIdKey() + "=?", new String[] {
                    Long.toString(persistable.getId())
                });
                db.close();
            }
        }
    }

    public static int booleanToInt(boolean value) {
        return value ? 1 : 0;
    }

    public static boolean intToBoolean(int value) {
        return value == 1 ? true : false;
    }
}
